package com.sixbro.distributed.lock.redis.result;

import com.sixbro.distributed.lock.redis.exception.ApiException;

import java.io.Serializable;

/**
 * <p>
 *  统一API对象返回
 * </p>
 *
 * @author: Mr.Lu
 * @since: 2021-12-20 14:19
 */
public class ApiResult<T> implements Serializable {
    private static final long serialVersionUID = -8713837118340960775L;

    /**
     * 状态码
     */
    private int code;
    /**
     * 返回消息
     */
    private String message;
    /**
     * 返回数据
     */
    private T data;

    /**
     * 无参构造函数
     */
    private ApiResult() {
    }

    /**
     * 全参构造函数
     *
     * @param code     状态码
     * @param message  返回内容
     * @param data     返回数据
     */
    private ApiResult(int code, String message, T data) {
        this.code = code;
        this.message = message;
        this.data = data;
    }

    public ApiResult<T> setCode(int code) {
        this.code = code;
        return this;
    }

    public ApiResult<T> setMessage(String message) {
        this.message = message;
        return this;
    }

    public ApiResult<T> setData(T data) {
        this.data = data;
        return this;
    }

    /**
     * 构造一个自定义的API返回
     *
     * @param code     状态码
     * @param message  返回内容
     * @param data     返回数据
     */
    public static <T> ApiResult of(int code, String message, T data) {
        return new ApiResult( code, message, data );
    }

    /**
     * 构造一个自定义且带数据的API返回
     *
     * @param resultCode  {@link IResultCode}
     * @param data        返回数据
     */
    public static <T> ApiResult of(IResultCode resultCode, T data) {
        return new ApiResult( resultCode.getCode(), resultCode.getMessage(), data );
    }

    /**
     * 构造一个成功的API返回
     *
     * @return ApiResult
     */
    public static ApiResult success() {
        return success(null);
    }

    /**
     * 构造一个成功且带数据的API返回
     *
     * @param data  返回数据
     * @return ApiResult
     */
    public static <T> ApiResult success(T data) {
        return of(ApiResultCode.SUCCESS, data);
    }

    public static ApiResult fail() {
        return fail(ApiResultCode.ERROR);
    }

    public static ApiResult fail(IResultCode resultCode) {
        return of(resultCode, null);
    }

    /**
     * 构造一个异常且带数据的API返回
     *
     * @param t     异常
     * @param <T>   {@link ApiException} 的子类
     * @return ApiResult
     */
    public static <T extends ApiException> ApiResult exception(T t) {
        return of(t.getCode(), t.getMessage(), null);
    }
}
